<?php

/**
 * Warlock Entry Point
 *
 * Initialises the core warlock framework and does
 * some initial controller processing before initialising
 * the requested application.
 *
 * Warlock is free software. This version may have been modified pursuant
 * to the GNU General Public License, and as distributed it includes or
 * is derivative of works licensed under the GNU General Public License or
 * other free or open source software licenses.
 *
 * @package    warlock`
 * @author     David Cole <neophyte@sourcetutor.com>
 * @license    GNU/GPL v2
 */

/*
 * Setup the basic warlock environment, this includes paths, constants as well as
 * the Vault, Profiling and Error objects.
 */

define('W_INIT',     true);                                                   // Mark Script Entry Point
define('W_ENV_PATH', dirname(__FILE__));                                      // Absolute path to warlock
define('W_ENV_URL',  dirname($_SERVER['SERVER_NAME'].$_SERVER['PHP_SELF']));  // URL to warlock
define('W_START',    array_sum(explode(' ', microtime())));                   // Warlock start time

// Add PEAR to the include_path
ini_set('include_path', './Library/PEAR:'.ini_get('include_path'));

// Handles Class and Library loading
require_once W_ENV_PATH.'/Engine/Vault.php';

// Get the profilier as early as possible to get a realistic bootstrap time
using('Engine.Profiling');
$profiler = &Vault::Get('Debug_Profiling');
$profiler->Start('Bootstrap System');

// Initialise the Error handler
using('Engine.Error');
$error = &Vault::Get('Debug_Error');

/*
 * We need to standardise the PHP environment as much as possible
 * before starting any real work
 */

$profiler->Start('Standardise PHP Environment');
require_once 'PHP/Compat.php';
PHP_Compat::loadEnvironment('magic_quotes_gpc',    'off');
PHP_Compat::loadEnvironment('magic_quotes_sybase', 'off');
PHP_Compat::loadEnvironment('register_globals',    'off');
PHP_Compat::loadVersion('4.3.0');
if (get_magic_quotes_runtime())	set_magic_quotes_runtime(0);
$profiler->Stop();

/*
 * Initialise the core warlock framework, this includes bringing in various
 * classes, functions and constants as well as instancing he core objects
 * which are used on every page load.
 */

$profiler->Start('Load Core Framework');

using('Engine.Model');
using('Engine.Observer');

$model    = &Vault::Get('Model');
$observer = &Vault::Get('Observer');
$config   = &Vault::Get('Config');

$profiler->Stop();

/*
 * Process and update the page model with relevent info from the URI and various other super globals
 * and info (determining the application to be initialised in the process).
 */

if (!$config->IsLoaded() || !$config->IsWritable() || !$config->Get('Warlock.installed'))
{
    // Either this is a first run or the config file is FUBAR so run the Installer
    $model->Set('Application', 'Installer');
}
else
{
    $uri = explode('/', substr($_SERVER['REQUEST_URI'], 1, -1));
    
    /*
     * Try and determine which application
     * should be used.
     */
    
    if (isset($uri[0]) && (strlen($uri[0]) > 0) && is_dir('Applications/'.($application = ucwords(strtolower($uri[0])))))
    {
        // Found a relevent application
        $model->Set('Application', $application);
    }
    else 
    {
        // Default to the Website application
        $model->Set('Application', 'Website');
    }                

    // Applications may as well use this as the basis for their respective controllers
    $model->Set('URI', $uri);   
}



/*
 * Include and Initialise the requested application
 * then continue with page execution
 */

$application = $model->Get('Application');
$profiler->Start('Initialise Application \''.$application.'\'');
using('Applications.'.$application.'.application');

if (class_exists(($class = 'Application_'.$application)))
{
    $error->Log('Starting Application \''.$application.'\'', W_LOG_DEBUG);
    $application = new $class();
}
else
    $error->Log('Unable to locate the application \''.$class.'\'', W_LOG_CRIT);
    
$profiler->Stop();

// Bootstrap Complete
$profiler->Stop();
$observer->RaiseEvent('onAfterBootstrap');

// The rest is upto the application
$profiler->Start('Run Application');
$application->Run();
$profiler->Stop();

/*
 * Application has run its course and we hopefully have a complete
 * model.
 */

switch (true)
{
    // User specified view eg. /?view=Debug
    case (isset($_GET['view']) && (strlen($_GET['view']) > 0) && ctype_alnum($_GET['view']) && is_dir('Views/'.$_GET['view'])):
        $model->Set('View', $_GET['view']);
        break;
        
    // Debug view just /?debug    
    case isset($_GET['debug']):
        $model->Set('View', 'Debug');
        break;
            
    // Alias of debug, maybe create seperate views?    
    case isset($_GET['profile']):
        $model->Set('View', 'Debug');
        break;        
        
    // Set the view to HTML if the application itself didnt select a view
    default:
        if (!$model->Get('View'))
            $model->Set('View', 'HTML');
}

$model->Set('Debug.Errors', $error->GetLog());
$model->Set('Debug.Profiling', $profiler->GetLog());

$view = $model->Get('View');
$profiler->Start('Initialise View \''.$view.'\'');
using('Views.'.$view.'.view');

if (class_exists($class = 'View_'.$view))
    $view = & new $class();
else
    $error->Log('Unable to Instance View \''.$class.'\'', W_LOG_CRIT);

// Should have a valid view, render the model    
$profiler->Start('Render Page Model');
$view->Render();
$profiler->Stop();

/*
 * At this point the application has run its course and the model
 * rendered by an appropriate view, all thats left to do is shutdown
 * warlock and output the generated content.
 */

$observer->RaiseEvent('onExit');
$view->Output();

?>